import { RouteObject } from "@/routes/interface";

/**
 * @description 获取需要展开的 subMenu
 * @param {String} path 当前访问地址
 * @returns array
 */
export const getOpenKeys = (path: string) => {
	let newStr: string = "";
	let newArr: any[] = [];
	let arr = path.split("/").map(i => "/" + i);
	for (let i = 1; i < arr.length - 1; i++) {
		newStr += arr[i];
		newArr.push(newStr);
	}
	return newArr;
};

/**
 * @description 递归查询对应的路由
 * @param {String} path 当前访问地址
 * @param {Array} routes 路由列表
 * @returns array
 */
export const searchRoute = (path: string, routes: RouteObject[] = []): RouteObject => {
	let result: RouteObject = {};
	for (let item of routes) {
		if (item.path === path) return item;
		if (item.children) {
			const res = searchRoute(path, item.children);
			if (Object.keys(res).length) result = res;
		}
	}
	return result;
};

/**
 * @description 使用递归处理路由菜单，生成一维数组，做菜单权限判断
 * @param {Array} menuList 所有菜单列表
 * @param {Array} newArr 菜单的一维数组
 * @return array
 */
export function handleRouter(routerList: Menu.MenuOptions[], newArr: string[] = []) {
	routerList.forEach((item: Menu.MenuOptions) => {
		typeof item === "object" && item.path && newArr.push(item.path);
		item.children && item.children.length && handleRouter(item.children, newArr);
	});
	return newArr;
}


// tree遍历为普通数组
export function TreeToArray(tree) {
	// 判断 tree 是否有值，无返回 []
	if (!Array.isArray(tree) || !tree.length) return [];
	let res = [];
	tree.forEach((v) => {
		// tree的每个元素都 放入到 res里面
		res.push(v);
		if (v.children) {
			// 有children 就把 children数据递归 返回  依次放到 res里面
			res.push(...TreeToArray(v.children));
		}
	});
	return res;
}


// 搜索返回新的tree数据
export const searchTree = (tree, keyword, includeChildren = false) => {
    const newTree = []
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i]
      if (node.title.includes(keyword)) {
        // 如果当前节点符合条件，则将其复制到新的树形结构中，并根据 includeChildren 参数决定是否将其所有子节点也复制到新的树形结构中
        newTree.push({ ...node, children: includeChildren ? searchTree(node.children || [], '', true) : [] })
      } else if (node.children) {
        // 如果当前节点不符合条件且存在子节点，则递归遍历子节点，以继续搜索
        const result = searchTree(node.children, keyword, true)
        if (result.length > 0) {
          // 如果子节点中存在符合条件的节点，则将其复制到新的树形结构中
          newTree.push({ ...node, children: result })
        }
      }
    }
    return newTree
  }


  /**
 * 防抖函数
 * 
 * @param {Function} func     函数
 * @param {number} wait       毫秒数
 * @param {boolean} immediate 到达边界不调用 
 * @return {*}
 */
export const debounce = (func: any, wait: number, immediate: boolean): any => {
	let timeout: NodeJS.Timeout | null, args: null, context: null | undefined, timestamp: number, result: any;

	const later = function () {
		// 据上一次触发时间间隔
		const last = +new Date() - timestamp;

		// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
		if (last < wait && last > 0) {
			timeout = setTimeout(later, wait - last);
		} else {
			timeout = null;
			// 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
			if (!immediate) {
				result = func.apply(context, args);
				if (!timeout) context = args = null;
			}
		}
	};

	return (...args: any) => {
		context = this;
		timestamp = +new Date();
		const callNow = immediate && !timeout;
		// 如果延时不存在，重新设定延时
		if (!timeout) timeout = setTimeout(later, wait);
		if (callNow) {
			result = func.apply(context, args);
			context = args = null;
		}

		return result;
	};
};


/**
 * 深克隆
 * 
 * @param {any} source
 * @returns {Object}
 */
export const deepClone = (source: any): object => {
	if (!source && typeof source !== "object") {
		throw new Error("error arguments");
	}
	const targetObj = source.constructor === Array ? [] : {};
	Object.keys(source).forEach((keys) => {
		if (source[keys] && typeof source[keys] === "object") {
			targetObj[keys] = deepClone(source[keys]);
		} else {
			targetObj[keys] = source[keys];
		}
	});
	return targetObj;
};